/**
 * @file bsp_i2c.c
 * @brief I2C封装驱动 \n
 * TODO:改进方向，中断发送、DMA接收
 * @author wangh (wanghuan3037@fiberhome.com)
 * @version 1.0
 * @date 2020-10-10
 * @copyright Copyright (c) 2020  烽火通信
 ***************************************************************
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version  <th>Author  <th>Description
 * <tr><td>2020-10-10 <td>1.0      <td>wangh   <td>内容
 * </table>
 */ 
#include "bsp_i2c.h"

#undef LOG_LEVEL_
#define LOG_LEVEL_ 	LOG_LVL_ASSERT
#include "bsp_log.h"


static void I2cConfig( I2c_t *obj );

/**
 * @brief I2C初始化
 * @param[in]  obj          I2C对象
 * @param[in]  i2cId        I2C外设编号 @ref I2cId_t
 * @param[in]  scl          时钟线
 * @param[in]  sda          数据线
 * @return int8_t 
 * - @b Success : BSP_SUCCESS \n
 * - @b Fail
 * - @ref BSP_ERROR_ALREADY_INIT - 已初始化
 * - @ref BSP_ERROR_INVALID_PARAM - 非法入参
 */
int8_t I2cInit( I2c_t *obj, I2cId_t i2cId, PinNames scl, PinNames sda )
{
    if ( (obj == NULL) || (i2cId > I2C_2) )
        return BSP_ERROR_INVALID_PARAM;

    if( obj->IsInitialized )
    {
        log_w( "I2C%d has already Initialized\r\n", i2cId );
        return BSP_ERROR_ALREADY_INIT;
    }

    if(i2cId == I2C_1)
    {
#ifdef STM32F10X
        obj->I2Cx = I2C1;
        RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C1, ENABLE );
#elif defined GD32F10X
        obj->I2Cx = I2C0;
        rcu_periph_clock_enable( RCU_I2C0 );
#endif
    }
    else if(i2cId == I2C_2)
    {
#ifdef STM32F10X
        obj->I2Cx = I2C2;
        RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C2, ENABLE );
#elif defined GD32F10X
        obj->I2Cx = I2C1;
        rcu_periph_clock_enable( RCU_I2C1 );
#endif
    }

    obj->I2cId = i2cId;
    obj->IsInitialized = true;
    GpioInit( &obj->Scl, scl, PIN_ALTERNATE_FCT, PIN_OPEN_DRAIN, PIN_NO_PULL, 0 );
    GpioInit( &obj->Sda, sda, PIN_ALTERNATE_FCT, PIN_OPEN_DRAIN, PIN_NO_PULL, 0 );

    I2cConfig( obj );
    // obj->I2cRegAddrSize = I2C_ADDR_SIZE_8;  /* 默认I2C从机寄存器寻址地址8位，可通过 I2cSetRegAddrSize() 设置 */

    return BSP_SUCCESS;
}

/**
 * @brief I2C去初始化
 * @param  obj         I2C对象
 */
void I2cDeInit( I2c_t *obj )
{
    if( obj && obj->IsInitialized )
    {
        obj->IsInitialized = false;
#ifdef STM32F10X
        I2C_DeInit( obj->I2Cx );
#elif defined GD32F10X
        i2c_deinit( obj->I2Cx );
#endif
        GpioInit( &obj->Scl, obj->Scl.pin, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
        GpioInit( &obj->Sda, obj->Sda.pin, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 );
    }
}

/**
 * @brief I2C复位总线
 * @param  obj         I2C对象
 */
void I2cResetBus( I2c_t *obj )
{
    if( obj && obj->IsInitialized )
    {
        obj->IsInitialized = false;
        I2cInit( obj, obj->I2cId, obj->Scl.pin, obj->Sda.pin );
    }
}

/**
 * @brief I2C参数配置
 * @param  obj         I2C对象
 */
static void I2cConfig( I2c_t *obj )
{
#ifdef STM32F10X
    I2C_InitTypeDef I2C_InitStructure;

    I2C_DeInit( obj->I2Cx );
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;  /* I2C模式 */
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;  /* I2C占空比，这个参数在快速I2C模式下有效，也就是速度大于100KHz */
    I2C_InitStructure.I2C_OwnAddress1 = 0x77;   /* I2C设备地址（从机） */
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; /* I2C应答 */
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;   /* 设备地址位数 */
    I2C_InitStructure.I2C_ClockSpeed = 10000;   /* I2C速度 */
    I2C_Init( obj->I2Cx, &I2C_InitStructure );
    I2C_Cmd( obj->I2Cx, ENABLE );
#elif defined GD32F10X
    i2c_clock_config( obj->I2Cx, 10000, I2C_DTCY_2 );
    i2c_mode_addr_config( obj->I2Cx, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0x77 );
    i2c_enable( obj->I2Cx );
    i2c_ack_config( obj->I2Cx, I2C_ACK_ENABLE );
#endif
}

/**
 * @brief 设置从机寻址地址位数
 * @param  obj         I2C对象
 * @param  addrSize    寻址地址位数 \n
 * @ref I2C_ADDR_SIZE_8 1个字节 \n
 * @ref I2C_ADDR_SIZE_16 2个字节
 */
void I2cSetRegAddrSize( I2c_t *obj, I2cRegAddrSize_t addrSize )
{
    if (obj != NULL) 
        obj->I2cRegAddrSize = addrSize;
}

#if !SIMPLE_I2C

#define I2C_TIMEOUT_MAX     0x8000

/**
 * @brief 等待 I2C_EVENT 事件置位 \n
 * @note 等待超时会复位总线
 * @param  obj         I2C对象
 * @param  event       I2C_EVENT
 * @param  status      循环检查的事件状态（期待状态反 ） \n
 * @ref SUCCESS 最后事件等于 I2C_EVENT \n
 * @ref ERROR 最后事件不等于 I2C_EVENT
 * @param  times       检查超时次数
 * @return true 成功
 * @return false 超时
 */
static bool I2cWaitCheckEvent( I2c_t *obj, uint32_t event, ErrorStatus status, uint32_t times )
{
    uint32_t timeOut = times;

    while( I2C_CheckEvent( obj->I2Cx, event ) == status ) /* 检测 I2C_EVENT */
    {
        if( ( timeOut-- ) == 0 )
        {
            I2cResetBus( obj ); /* 超时尝试复位I2C总线 */
            return false;
        }
    }
    return true;
}

/**
 * @brief 等待 I2C_FLAG 
 * @param  obj         I2C对象
 * @param  flag        I2C_FLAG
 * @param  status      循环检查的标志状态（期待状态反） \n
 * @ref SET I2C_FLAG置位 \n
 * @ref RESET I2C_FLAG清零
 * @param  times       检查超时次数
 * @return true 成功
 * @return false 超时
 */
static bool I2cWaitGetFlagStatus( I2c_t *obj, uint32_t flag, bool status, uint32_t times )
{
    uint32_t timeOut = times;
    while( I2C_GetFlagStatus( obj->I2Cx, flag) == status )    /* 检测 I2C_FLAG */
    {
        if( ( timeOut-- ) == 0 )
        {
            I2cResetBus( obj );
            return false;
        }
    }
    return true;
}

/**
 * @brief I2C写数据
 * @param[in]  obj          I2C对象
 * @param[in]  deviceAddr   从机设备地址
 * @param[in]  addr         从机寻址地址
 * @param[in]  buffer       写数据指针
 * @param[in]  size         写数据长度
 * @return int8_t 
 * - @b Success : BSP_SUCCESS \n
 * - @b Fail
 * - @ref BSP_ERROR_INVALID_PARAM
 * - @ref BSP_ERROR
 */
int8_t I2cWriteBuffer( I2c_t *obj, uint8_t deviceAddr, uint16_t addr, uint8_t *buffer, uint16_t size )
{
    if ( (obj == NULL) || (buffer == NULL) || (size == 0) )
        return BSP_ERROR_INVALID_PARAM;
    
    if (!obj->IsInitialized)
        return BSP_ERROR_NO_INIT;

    ENTER_CRITICAL( );  /* I2C通信临界区保护(不存在多线程问题) */
    /* 检测总线是否空闲 */
    if(!I2cWaitGetFlagStatus( obj, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_MAX ))
    {
        EXIT_CRITICAL( );
        log_v( "I2C_FLAG_BUSY wait timeout\r\n" );
        return BSP_ERROR;
    }

    /* 产生起始 */
    I2C_GenerateSTART( obj->I2Cx, ENABLE );
    if(!I2cWaitCheckEvent( obj, I2C_EVENT_MASTER_MODE_SELECT, ERROR, I2C_TIMEOUT_MAX ))    /* 检测EV5 */
    {
        EXIT_CRITICAL( );
        log_v( "I2C_GenerateSTART I2C_EVENT_MASTER_MODE_SELECT wait timeout\r\n" );
        return BSP_ERROR;
    }

    /* 发送从机设备地址写 */
    I2C_Send7bitAddress( obj->I2Cx, deviceAddr, I2C_Direction_Transmitter );
    if(!I2cWaitCheckEvent( obj, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED, ERROR, I2C_TIMEOUT_MAX ))  /* 检测EV6 */
    {
        EXIT_CRITICAL( );
        log_v( "I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED wait timeout\r\n" );
        return BSP_ERROR;
    }

    /* 发送寻址地址 */
    if( obj->I2cRegAddrSize == I2C_ADDR_SIZE_16 )
    {
        I2C_SendData( obj->I2Cx, ( uint8_t )( ( addr & 0xFF00 ) >> 8 ) );    /* 发送寻址地址MSB */
        if(!I2cWaitCheckEvent( obj, I2C_EVENT_MASTER_BYTE_TRANSMITTING, ERROR, I2C_TIMEOUT_MAX ))  /* 检测EV8 */
        {
            EXIT_CRITICAL( );
            log_v( "I2C_EVENT_MASTER_BYTE_TRANSMITTING wait timeout\r\n" );
            return BSP_ERROR;
        }
    }
    I2C_SendData( obj->I2Cx, ( uint8_t )( addr & 0x00FF ) ); /* 发送寻址地址LSB */
    if(!I2cWaitCheckEvent( obj, I2C_EVENT_MASTER_BYTE_TRANSMITTING, ERROR, I2C_TIMEOUT_MAX ))  /* 检测EV8 */
    {
        EXIT_CRITICAL( );
        log_v( "I2C_EVENT_MASTER_BYTE_TRANSMITTING wait timeout\r\n" );
        return BSP_ERROR;
    }

    /* 连续写数据 */
    while( size-- )
    {
        I2C_SendData( obj->I2Cx, *buffer ); /* 发送1字节 */
        if(!I2cWaitCheckEvent( obj, I2C_EVENT_MASTER_BYTE_TRANSMITTING, ERROR, I2C_TIMEOUT_MAX ))  /* 检测EV8 */
        {
            EXIT_CRITICAL( );
            log_v( "I2C_EVENT_MASTER_BYTE_TRANSMITTING wait timeout\r\n" );
            return BSP_ERROR;
        }
        
        buffer++;
    }

    /* 产生停止 */
    I2C_GenerateSTOP( obj->I2Cx, ENABLE );

    EXIT_CRITICAL( );
    return BSP_SUCCESS;
}

/**
 * @brief I2C读数据
 * @param[in]  obj          I2C对象
 * @param[in]  deviceAddr   从机设备地址
 * @param[in]  addr         从机寻址地址
 * @param[in]  buffer       读取缓存
 * @param[in]  size         读取长度
 * @return int8_t 
 * - @b Success : BSP_SUCCESS \n
 * - @b Fail
 * - @ref BSP_ERROR_INVALID_PARAM
 * - @ref BSP_ERROR
 */
int8_t I2cReadBuffer( I2c_t *obj, uint8_t deviceAddr, uint16_t addr, uint8_t *buffer, uint16_t size )
{
    if ( (obj == NULL) || (buffer == NULL) || (size == 0) )
        return BSP_ERROR_INVALID_PARAM;
    
    if (!obj->IsInitialized)
        return BSP_ERROR_NO_INIT;

    ENTER_CRITICAL( );  /* 进入临界区 */
    /* 检测总线是否空闲 */
    if(!I2cWaitGetFlagStatus( obj, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_MAX ))
    {
        EXIT_CRITICAL( );   /* 退出临界区 */
        log_v( "I2C_FLAG_BUSY wait timeout\r\n" );
        return BSP_ERROR;
    }
    I2C_AcknowledgeConfig( obj->I2Cx, ENABLE ); /* I2C自动应答使能 */

    /* 产生起始 */
    I2C_GenerateSTART( obj->I2Cx, ENABLE );
    if(!I2cWaitCheckEvent( obj, I2C_EVENT_MASTER_MODE_SELECT, ERROR, I2C_TIMEOUT_MAX ))    /* 检测EV5 */
    {
        EXIT_CRITICAL( );
        log_v( "I2C_EVENT_MASTER_MODE_SELECT wait timeout\r\n" );
        return BSP_ERROR;
    }

    /* 发送从机设备地址写 */
    I2C_Send7bitAddress( obj->I2Cx, deviceAddr, I2C_Direction_Transmitter );
    if(!I2cWaitCheckEvent( obj, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED, ERROR, I2C_TIMEOUT_MAX ))  /* 检测EV6 */
    {
        EXIT_CRITICAL( );
        log_v( "I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED wait timeout\r\n" );
        return BSP_ERROR;
    }

    /* 发送寻址地址 */
    if( obj->I2cRegAddrSize == I2C_ADDR_SIZE_16 )
    {
        I2C_SendData( obj->I2Cx, ( uint8_t )( ( addr & 0xFF00 ) >> 8 ) );    /* 发送寻址地址MSB */
        if(!I2cWaitCheckEvent( obj, I2C_EVENT_MASTER_BYTE_TRANSMITTING, ERROR, I2C_TIMEOUT_MAX ))  /* 检测EV8 */
        {
            EXIT_CRITICAL( );
            log_v( "I2C_EVENT_MASTER_BYTE_TRANSMITTING wait timeout\r\n" );
            return BSP_ERROR;
        }
    }
    I2C_SendData( obj->I2Cx, ( uint8_t )( addr & 0x00FF ) ); /* 发送寻址地址LSB */
    if(!I2cWaitCheckEvent( obj, I2C_EVENT_MASTER_BYTE_TRANSMITTING, ERROR, I2C_TIMEOUT_MAX ))  /* 检测EV8 */
    {
        EXIT_CRITICAL( );
        log_v( "I2C_EVENT_MASTER_BYTE_TRANSMITTING wait timeout\r\n" );
        return BSP_ERROR;
    }

    // /* 字传输完成标志 */
    // if(!I2cWaitGetFlagStatus( obj, I2C_FLAG_BTF, RESET, I2C_TIMEOUT_MAX ))    /* 检测EV8 */
    // {
    //     EXIT_CRITICAL( );
    //     return BSP_ERROR;
    // }

    /* 重新产生起始 */
    I2C_GenerateSTART( obj->I2Cx, ENABLE );
    if(!I2cWaitCheckEvent( obj, I2C_EVENT_MASTER_MODE_SELECT, ERROR, I2C_TIMEOUT_MAX ))    /* 检测EV5 */
    {
        EXIT_CRITICAL( );
        log_v( "I2C_EVENT_MASTER_MODE_SELECT wait timeout\r\n" );
        return BSP_ERROR;
    }

    /* 发送从机设备地址读 */
    I2C_Send7bitAddress( obj->I2Cx, deviceAddr, I2C_Direction_Receiver );
    if(!I2cWaitCheckEvent( obj, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED, ERROR, I2C_TIMEOUT_MAX ))  /* 检测EV6 */
    {
        EXIT_CRITICAL( );
        log_v( "I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED wait timeout\r\n" );
        return BSP_ERROR;
    }

    /* 连续读数据 */
    while( size > 1 )
    {
        if(!I2cWaitGetFlagStatus( obj, I2C_FLAG_RXNE, RESET, I2C_TIMEOUT_MAX ))   /* 等待接收标志 */
        {
            EXIT_CRITICAL( );
            log_v( "I2C_FLAG_RXNE wait timeout\r\n" );
            return BSP_ERROR;
        }
        *buffer = I2C_ReceiveData( obj->I2Cx );
        buffer++;
        size--;
    }

    /* 接收最后一个字节 */
    I2C_AcknowledgeConfig( obj->I2Cx, DISABLE );    /* 非应答 */
    if(!I2cWaitGetFlagStatus( obj, I2C_FLAG_RXNE, RESET, I2C_TIMEOUT_MAX ))   /* 等待接收标志 */
    {
        EXIT_CRITICAL( );
        log_v( "I2C_FLAG_RXNE wait timeout\r\n" );
        return BSP_ERROR;
    }
    *buffer = I2C_ReceiveData( obj->I2Cx );
    I2C_GenerateSTOP( obj->I2Cx, ENABLE );  /* 产生停止 */

    I2C_AcknowledgeConfig( obj->I2Cx, ENABLE ); /* I2C恢复自动应答使能 */

    EXIT_CRITICAL( );
    return BSP_SUCCESS;
}

#else
/**
 * @brief I2C写数据
 * @param[in]  obj          I2C对象
 * @param[in]  deviceAddr   从机设备地址
 * @param[in]  addr         从机寻址地址
 * @param[in]  buffer       写数据指针
 * @param[in]  size         写数据长度
 * @return int8_t 
 * - @b Success : BSP_SUCCESS \n
 * - @b Fail
 * - @ref BSP_ERROR_INVALID_PARAM
 * - @ref BSP_ERROR
 */
int8_t I2cWriteBuffer( I2c_t *obj, uint8_t deviceAddr, uint16_t addr, uint8_t *buffer, uint16_t size )
{
    if ( (obj == NULL) || (buffer == NULL) || (size == 0) )
        return BSP_ERROR_INVALID_PARAM;
    
    if (!obj->IsInitialized)
        return BSP_ERROR_NO_INIT;

#ifdef STM32F10X
    I2C_AcknowledgeConfig( obj->I2Cx, ENABLE ); 
    I2C_GenerateSTART( obj->I2Cx, ENABLE); 
    while(!I2C_CheckEvent( obj->I2Cx, I2C_EVENT_MASTER_MODE_SELECT )){;}

    I2C_Send7bitAddress( obj->I2Cx, deviceAddr, I2C_Direction_Transmitter ); 
    while(!I2C_CheckEvent( obj->I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED )){;}

    I2C_SendData( obj->I2Cx, addr );
    while(!I2C_CheckEvent( obj->I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED )){;}

    for (uint16_t i=0; i<size; i++)
    {
        I2C_SendData( obj->I2Cx, *buffer );
        while(!I2C_CheckEvent( obj->I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED )){;}
        buffer++;
    }
    I2C_GenerateSTOP( obj->I2Cx, ENABLE );

#elif defined GD32F10X
    i2c_ack_config( obj->I2Cx, I2C_ACK_ENABLE );
    i2c_start_on_bus( obj->I2Cx );
    while(!i2c_flag_get( obj->I2Cx, I2C_FLAG_SBSEND ));

    i2c_master_addressing( obj->I2Cx, deviceAddr, I2C_TRANSMITTER );
    while(!i2c_flag_get( obj->I2Cx, I2C_FLAG_ADDSEND ));
    i2c_flag_clear( obj->I2Cx, I2C_FLAG_ADDSEND );

    i2c_data_transmit( obj->I2Cx, addr );
    while(!i2c_flag_get( obj->I2Cx, I2C_FLAG_TBE ));

    for (uint16_t i=0; i<size; i++)
    {
        i2c_data_transmit( obj->I2Cx, buffer[i] );
        while(!i2c_flag_get( obj->I2Cx, I2C_FLAG_TBE ));
    }
    i2c_stop_on_bus( obj->I2Cx );
#endif

    return BSP_SUCCESS;
}

/**
 * @brief I2C读数据
 * @param[in]  obj          I2C对象
 * @param[in]  deviceAddr   从机设备地址
 * @param[in]  addr         从机寻址地址
 * @param[in]  buffer       读取缓存
 * @param[in]  size         读取长度
 * @return int8_t 
 * - @b Success : BSP_SUCCESS \n
 * - @b Fail
 * - @ref BSP_ERROR_INVALID_PARAM
 * - @ref BSP_ERROR
 */
int8_t I2cReadBuffer( I2c_t *obj, uint8_t deviceAddr, uint16_t addr, uint8_t *buffer, uint16_t size )
{
    if ( (obj == NULL) || (buffer == NULL) || (size == 0) )
        return BSP_ERROR_INVALID_PARAM;
    
    if (!obj->IsInitialized)
        return BSP_ERROR_NO_INIT;

#ifdef STM32F10X
    I2C_AcknowledgeConfig( obj->I2Cx, ENABLE );
    I2C_GenerateSTART( obj->I2Cx, ENABLE );
    while(!I2C_CheckEvent( obj->I2Cx, I2C_EVENT_MASTER_MODE_SELECT )){;}

    I2C_Send7bitAddress( obj->I2Cx, deviceAddr, I2C_Direction_Transmitter );
    while(!I2C_CheckEvent( obj->I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED )){;}

    I2C_SendData( obj->I2Cx, addr );
    while(!I2C_CheckEvent( obj->I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED )){;}
    
    I2C_GenerateSTART( obj->I2Cx, ENABLE );
    while(!I2C_CheckEvent( obj->I2Cx, I2C_EVENT_MASTER_MODE_SELECT )){;}

    I2C_Send7bitAddress( obj->I2Cx, deviceAddr, I2C_Direction_Receiver );
    while(!I2C_CheckEvent( obj->I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED )){;}

    for (uint16_t i=0; i<size-1; i++)
    {
        I2C_AcknowledgeConfig( obj->I2Cx, ENABLE );
        while( I2C_GetFlagStatus( obj->I2Cx, I2C_FLAG_RXNE ) == RESET );
        *buffer = I2C_ReceiveData( obj->I2Cx );
        buffer++;
    }

    I2C_AcknowledgeConfig( obj->I2Cx, DISABLE);
    while( I2C_GetFlagStatus( obj->I2Cx, I2C_FLAG_RXNE ) == RESET );
    *buffer = I2C_ReceiveData( obj->I2Cx );

    I2C_GenerateSTOP( obj->I2Cx, ENABLE );

#elif defined GD32F10X
    i2c_ack_config( obj->I2Cx, I2C_ACK_ENABLE );
    i2c_start_on_bus( obj->I2Cx );
    while(!i2c_flag_get( obj->I2Cx, I2C_FLAG_SBSEND ));

    i2c_master_addressing( obj->I2Cx, deviceAddr, I2C_TRANSMITTER );
    while(!i2c_flag_get( obj->I2Cx, I2C_FLAG_ADDSEND ));
    i2c_flag_clear( obj->I2Cx, I2C_FLAG_ADDSEND );

    i2c_data_transmit( obj->I2Cx, addr );
    while(!i2c_flag_get( obj->I2Cx, I2C_FLAG_TBE ));

    i2c_start_on_bus( obj->I2Cx );
    while(!i2c_flag_get( obj->I2Cx, I2C_FLAG_SBSEND ));

    i2c_master_addressing( obj->I2Cx, deviceAddr, I2C_RECEIVER );
    while(!i2c_flag_get( obj->I2Cx, I2C_FLAG_ADDSEND ));
    i2c_flag_clear( obj->I2Cx, I2C_FLAG_ADDSEND );

    for (uint16_t i=0; i<size-1; i++)
    {
        while(!i2c_flag_get( obj->I2Cx, I2C_FLAG_RBNE ));
        *buffer = i2c_data_receive( obj->I2Cx );
        buffer++;
    }

    i2c_ack_config( obj->I2Cx, I2C_ACK_DISABLE );
    while(!i2c_flag_get( obj->I2Cx, I2C_FLAG_RBNE ));
    *buffer = i2c_data_receive( obj->I2Cx );

    i2c_stop_on_bus( obj->I2Cx );
    i2c_ack_config( obj->I2Cx, I2C_ACK_ENABLE );
#endif

    return BSP_SUCCESS;
}

#endif  /* SIMPLE_I2C */

/*********** (C) COPYRIGHT 2020 FiberHome *****END OF FILE****/
